home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 June / Macworld (1999-06).dmg / Shareware World / Info / For Developers / MacZoop2.0.sea / MacZoop2.0 / Required Classes / ZObject.h < prev    next >
Text File  |  1999-02-24  |  4KB  |  136 lines

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            MacZoop - "the framework for the rest of us"         
  5. *
  6. *
  7. *
  8. *            ZObject.h            -- the root object (abstract class)
  9. *
  10. *
  11. *
  12. *
  13. *
  14. *            © 1998, Graham Cox
  15. *
  16. *
  17. *
  18. *
  19. *************************************************************************************************/
  20.  
  21.  
  22. #pragma once
  23.  
  24. #ifndef __ZOBJECT__
  25. #define    __ZOBJECT__
  26.  
  27. class    ZObject;
  28. class    ZStream;
  29. class    ZClassRegistry;
  30.  
  31. typedef ZObject* (*ConstructorFunction)();
  32.  
  33. /*
  34.  
  35. In order to permit MacZoop to implement object streaming (persistent objects), all objects
  36. need to have a common root. This is it- ZObject. Most classes ultimately derive from this and
  37. are thus streamable.
  38.  
  39. ZObject relies on ZClassRegistry to store a table of class ID's, names and intantiation
  40. functions. Every class you wish to create from a stream must be registered with <gClasses> in
  41. order to work- this is normally done at app startup time when ZApplication's RegisterClasses()
  42. method is called. The standard method only registers the required classes.
  43.  
  44. Class ID's are four-char codes. MacZoop reserves all lower-case only codes for itself- for
  45. classes of your own, use one or more upper case letters and make sure it's unique. The classID
  46. must be assigned in your constructor.
  47.  
  48. In addition, all streamable classes must have a default constructor- i.e. one that has no
  49. parameters. You must also write a CONSTRUCTION FUNCTION, which just makes an object of the
  50. declared type using the default constructor. This goes like this:
  51.  
  52. ZObject*    MyConstructorFunction()
  53. {
  54.     return new MyClass();
  55. }
  56.  
  57. The function is passed to ZClassRegistry's RegisterClass() method, along with the classID and
  58. class name.
  59.  
  60. The following macros are provided to make all this setup much easier. They expand to the proper
  61. class ID and constructor function defeinitions so you can simply deploy them in your classes and
  62. forget about 'em.
  63.  
  64. */
  65.  
  66. // This handy macro saves you having to do much work to create you class constructor functions. All
  67. // you have to do is put this at the top of your .cpp file where you want a constructor function,
  68. // passing the class name. This will be expanded into a constructor function of the correct type.
  69. // i.e. CLASSCONSTRUCTOR( ZWindow ); -> ZObject* CF_ZWindow() { return new ZWindow(); };
  70.  
  71. #define        CLASSCONSTRUCTOR( x )        ZObject*    CF_##x##() { return new x(); }
  72.  
  73. // to place a prototype for the constructor function, use this. NOte that normally this is unnecessary
  74. // since the DEFINECLASSID will also do this for you in the appropriate place.
  75.  
  76. #define        CLASSCFPROTOTYPE( x )        ZObject*    CF_##x##()
  77.  
  78. // to establish the proper class ID identifier for your class, put this in your class header:
  79. // x is the class identifier, e.g. ZWindow, id is the desired ID, e.g. 'zwin'.
  80.  
  81. #define        DEFINECLASSID( x, id )        enum {    CLASS_##x = id }; CLASSCFPROTOTYPE( x )
  82.  
  83. // to determine the name of the constructor function from your class identifier, use:
  84.  
  85. #define        CONSTRUCTORFUNCTION( x )    CF_##x
  86.  
  87. // to make a readable pascal style class name for your class:
  88.  
  89. #define        CLASSNAME( x )    CLITERAL( \p##x )
  90.  
  91. // handy way to get your class ID from your class name
  92.  
  93. #define        CLASSID( x )    CLASS_##x
  94.  
  95.  
  96. // So when registering a class, you need only do:
  97. // gClasses->RegisterClass( CLASSID( ZWindow ), CONSTRUCTORFUNCTION( ZWindow ), CLASSNAME( ZWindow ));
  98.  
  99. // even better, ZClassRegistry has a macro that expands to this from a single class identifier:
  100. // e.g. REGISTERCLASS( ZWindow );
  101.  
  102.  
  103.  
  104. DEFINECLASSID( ZObject, 'zobj' );
  105.  
  106. // class definition:
  107.  
  108. class    ZObject
  109. {
  110. protected:
  111.     OSType        classID;                            // class ID of object- subclasses must set this
  112.     long        instanceID;                            // instance ID- not yet used. Reserved.
  113.     
  114. public:
  115.     ZObject() { classID = CLASS_ZObject; instanceID = 0; };
  116.     virtual ~ZObject(){};
  117.     
  118. // info:
  119.     void    GetClassName( Str255 aName );
  120.     long    GetClassRef() { return classID; };
  121.     long    GetInstanceID() { return instanceID; };
  122.     void    SetClassID( OSType id ) { classID = id; };
  123.     
  124. // streaming:
  125.     virtual void    ReadFromStream( ZStream* aStream ) {};
  126.     virtual void    WriteToStream( ZStream* aStream ) {};
  127. };
  128.  
  129.  
  130.  
  131. extern ZClassRegistry*    gClasses;
  132.  
  133.  
  134.  
  135. #endif
  136.